package com.gogant.spider.http;

import java.io.CharArrayReader;
import java.io.IOException;

import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML.Tag;
import javax.swing.text.html.HTMLEditorKit.ParserCallback;
import javax.swing.text.html.parser.ParserDelegator;


public class HtmlHelper {
	private static ParserDelegator parser = new ParserDelegator();

	public static boolean isHtmlResponse(HttpResponse resp) {
		String contentType = resp.getContentType();
		if (contentType == null || !contentType.startsWith("text/html")) {
			return false;
		} else {
			return true;
		}
	}

	public static boolean parseHtml(String html, HtmlSelector selector) {
		if (html == null || html.length() == 0 || selector == null) {
			return false;
		}
		try {
			selector.reset();
			parser.parse(new CharArrayReader(html.toCharArray()), selector, true);
			return true;
		} catch (IOException e) {
			return false;
		}
	}

	public static boolean parseHtml(String html, HtmlSelector[] selectors) {
		if (html == null || html.length() == 0 || selectors == null || selectors.length == 0) {
			return false;
		}
		try {
			for (HtmlSelector selector : selectors) {
				selector.reset();
			}
			ParserCallback callback = selectors.length == 1 ? selectors[0] : new MultiHtmlSelector(selectors);
			parser.parse(new CharArrayReader(html.toCharArray()), callback, true);
			return true;
		} catch (IOException e) {
			return false;
		}
	}

	public static boolean parseHtml(HttpResponse resp, HtmlSelector selector) {
		if (!resp.isOK() || !isHtmlResponse(resp)) {
			return false;
		}
		return parseHtml(resp.getTextContent(), selector);
	}

	public static boolean parseHtml(HttpResponse resp, HtmlSelector[] selectors) {
		if (!resp.isOK() || !isHtmlResponse(resp)) {
			return false;
		}
		return parseHtml(resp.getTextContent(), selectors);
	}

	public static boolean parseHtml(String html, ParserCallback callback) {
		if (html == null || html.length() == 0 || callback == null) {
			return false;
		}
		try {
			parser.parse(new CharArrayReader(html.toCharArray()), callback, true);
			return true;
		} catch (IOException e) {
			return false;
		}
	}

	public static boolean parseHtml(HttpResponse resp, ParserCallback callback) {
		if (!resp.isOK() || !isHtmlResponse(resp)) {
			return false;
		}
		return parseHtml(resp.getTextContent(), callback);
	}

	private static class MultiHtmlSelector extends ParserCallback {
		private HtmlSelector[] selectors;

		public MultiHtmlSelector(HtmlSelector[] selectors) {
			this.selectors = selectors;
		}

		@Override
		public void handleSimpleTag(Tag t, MutableAttributeSet a, int pos) {
			for (HtmlSelector selector : selectors) {
				selector.handleSimpleTag(t, a, pos);
			}
		}

		@Override
		public void handleStartTag(Tag t, MutableAttributeSet a, int pos) {
			for (HtmlSelector selector : selectors) {
				selector.handleStartTag(t, a, pos);
			}
		}

		@Override
		public void handleEndTag(Tag t, int pos) {
			for (HtmlSelector selector : selectors) {
				selector.handleEndTag(t, pos);
			}
		}

		@Override
		public void handleText(char[] data, int pos) {
			for (HtmlSelector selector : selectors) {
				selector.handleText(data, pos);
			}
		}
	}
}
